<?php
/**
 * Plugin Name:     WP GraphiQL
 * Plugin URI:      https://wpgraphql.com
 * Description:     This plugin provides the GraphiQL IDE as an admin page in WordPress, allowing the GraphQL WPGraphQL
 * schema to be browsed from within WordPress.
 * Author:          WPGraphQL, Digital First Media, Jason Bahl
 * Author URI:      http://wpgraphql.com
 * Text Domain:     wp-graphiql
 * Domain Path:     /languages
 * Version:         1.0.1
 *
 * @package         WPGraphiql
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'WPGraphiQL' ) ) :

class WPGraphiQL {

	public function init() {
		if ( ! defined( 'WPGRAPHIQL_PLUGIN_DIR' ) ) {
			define( 'WPGRAPHIQL_PLUGIN_DIR', plugin_dir_url( __FILE__ ) );
		}
		add_action( 'admin_menu', [ $this, 'register_admin_page' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_react_app' ] );
	}

	public function is_wpgraphql_active() {
		return class_exists( 'WPGraphQL' );
	}

	public function register_admin_page() {
		add_menu_page(
			__( 'GraphiQL', 'wp-graphiql' ),
			'GraphiQL',
			'manage_options',
			'wp-graphiql/wp-graphiql.php',
			[ $this, 'render_admin_page' ],
			''
		);
	}

	public function render_admin_page() {

		if ( $this->is_wpgraphql_active() ) {
			echo '<div class="wrap"><div id="wp-graphiql" class="graphiql-container">Loading ...</div></div>';
		} else {
			echo '<div class="wrap"><h1>This plugin requires WPGraphQL to be installed to work. Please install WPGraphQL (https://github.com/wp-graphql/wp-graphql) and visit this page again.</h1></div>';
		}

	}

	/**
	 * Gets the contents of the Create React App manifest file
	 *
	 * @return array|bool|string
	 */
	public function get_app_manifest() {
		$manifest = file_get_contents( dirname( __FILE__ ) . '/assets/app/build/asset-manifest.json' );
		$manifest = (array) json_decode( $manifest );
		return $manifest;
	}

	/**
	 * Gets the path to the stylesheet compiled by Create React App
	 *
	 * @return string
	 */
	public function get_app_stylesheet() {
		$manifest = $this->get_app_manifest();
		if ( empty( $manifest['main.css'] ) ) {
			return '';
		}
		return WPGRAPHIQL_PLUGIN_DIR . 'assets/app/build/' . $manifest['main.css'];
	}

	/**
	 * Gets the path to the built javascript file compiled by Create React App
	 *
	 * @return string
	 */
	public function get_app_script() {
		$manifest = $this->get_app_manifest();
		if ( empty( $manifest['main.js'] ) ) {
			return '';
		}
		return WPGRAPHIQL_PLUGIN_DIR . 'assets/app/build/' . $manifest['main.js'];
	}

	public function get_app_script_helpers() {
		$manifest = $this->get_app_manifest();
		if ( empty( $manifest['main.js'] ) ) {
			return '';
		}
		return WPGRAPHIQL_PLUGIN_DIR . 'assets/js/wp-graphiql-helpers.js';
	}

	/**
	 * Enqueues the stylesheet and js for the WPGraphiQL app
	 */
	public function enqueue_react_app() {

		/**
		 * Only enqueue the assets on the proper admin page, and only if WPGraphQL is also active
		 */
		if ( strpos( get_current_screen()->id, 'wp-graphiql/wp-graphiql' ) && $this->is_wpgraphql_active() ) {

			wp_enqueue_style( 'wp-graphiql', $this->get_app_stylesheet(), array(), false, false );
			wp_enqueue_script( 'wp-graphiql-helpers', $this->get_app_script_helpers(), array( 'jquery' ), false, true );
			wp_enqueue_script( 'wp-graphiql', $this->get_app_script(), array(), false, true );

			/**
			 * Create a nonce
			 */
			wp_localize_script(
				'wp-graphiql',
				'wpGraphiQLSettings',
				array(
					'nonce' => wp_create_nonce( 'wp_rest' ),
					'graphqlEndpoint' => trailingslashit( site_url() ) . 'index.php?' . \WPGraphQL\Router::$route,
				)
			);

		}
	}

}

endif; // End if class_exists()

add_action( 'plugins_loaded', function() {

	$wp_graphiql = new WPGraphiQL();
	$wp_graphiql->init();

} );
